/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package jus.aor.printing;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Thomas
 */
public class TCP {

    /**
     * Transmission par TCP d'une notification.
     *
     * @param soc la socket sur laquelle envoyé
     * @param notification la notification a transmettre.
     */
    static void writeProtocole(Socket soc, Notification notification) {
        ObjectOutputStream os;
        try {
            os = new ObjectOutputStream(soc.getOutputStream());
            os.writeObject(notification);
            os.flush();
        } catch (IOException ex) {
            Logger.getLogger(TCP.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    /**
     * Lit une notification transmisse par TCP.
     *
     * @param soc la socket en écoute.
     * @return la notification reçue.
     */
    public static Notification readProtocole(Socket soc) {
        try {
            ObjectInputStream is = new ObjectInputStream(soc.getInputStream());
            Notification notif = (Notification) is.readObject();
            return notif; // on récupere la notification.

        } catch (IOException ex) {
            Logger.getLogger(TCP.class.getName()).log(Level.SEVERE, null, ex);
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(TCP.class.getName()).log(Level.SEVERE, null, ex);
        }
        return Notification.QUERRY_UNKNOWN_ERROR;
    }

    /**
     * Transmet un Jobkey par marshalling.
     *
     * @param soc
     * @param job
     */
    public static void writeJobKey(Socket soc, JobKey job) throws IOException {
        byte[] marshal = job.marshal();
        writeBytes(soc, marshal, marshal.length);
    }

    /**
     * Transfert d'un tableau de byte.
     *
     * @param soc la socket
     * @param marshall le tableau de byte
     * @param start ou commence le tableau
     * @param len longueur du tableau de byte
     * @throws IOException
     */
    protected static void writeBytes(Socket soc, byte[] marshall, int len) {
        if (len < 0) {
            throw new IllegalArgumentException("taille négative !");
        }
        OutputStream out;
        try {
            out = soc.getOutputStream();
            DataOutputStream dos = new DataOutputStream(out);

            dos.writeInt(len);
            if (len > 0) {
                dos.write(marshall, 0, len);
            }
        } catch (IOException ex) {
            Logger.getLogger(TCP.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    /**
     * Lecture de Bytes.
     *
     * @param soc
     * @return
     * @throws IOException
     */
    protected static byte[] readBytes(Socket soc) throws IOException {
        InputStream in = soc.getInputStream();
        DataInputStream dis = new DataInputStream(in);

        int len = dis.readInt();
        byte[] data = new byte[len];
        if (len > 0) {
            dis.readFully(data);
        }
        return data;
    }

    /**
     * lit un Jobkey transmit par marshalling.
     *
     * @param soc
     * @return le jobkey
     */
    public static JobKey readJobKey(Socket soc) throws IOException {
        JobKey job = new JobKey(readBytes(soc));
        return job;
    }

    public static String readData(Socket soc) {
        String s = "";
        try {
            s = new String(readBytes(soc));
        } catch (IOException ex) {
            Logger.getLogger(TCP.class.getName()).log(Level.SEVERE, null, ex);
        }
        return s;
    }

    public static void writeData(Socket soc, InputStream fis, int len) {
        byte[] bytes;
        try {
            bytes = new byte[fis.available()];
            fis.read(bytes);
            writeBytes(soc, bytes, len);

        } catch (IOException ex) {
            Logger.getLogger(TCP.class.getName()).log(Level.SEVERE, null, ex);
        }

    }
}
